import os

from docutils.core import publish_parts

from google.appengine.ext import db
from google.appengine.ext.webapp import template

from model import Author, Collection, Exposition, Picture

from tools import manager
from tools import collection_manager, author_manager, exposition_manager

class PictureManager(manager.Manager):
    """
    """

    def __get_pictures(self, fetched_pictures, nb_of_pictures):
        """
        """
        # xy llist for html table display
        x_list_pictures = list()
        y_list_pictures = list()

        for picture in fetched_pictures:
            # tests
            if len(x_list_pictures) < nb_of_pictures:
                pass

            elif len(y_list_pictures) < nb_of_pictures:
                y_list_pictures.append(x_list_pictures)
                # x_list reset
                x_list_pictures = list()

            else:
                break

            # feeding
            x_list_pictures.append(picture)

        # last feeding
        if len(y_list_pictures) < nb_of_pictures:
            y_list_pictures.append(x_list_pictures)

        return y_list_pictures

    def __get_all_nb_of_pictures(self):
        """
        """
        # list of sizes to return
        list_nb_of_pictures = list()

        # 1x1 item
        item_nb_of_picture = {
                    'name': '1x1',
                    'value': 1}
        list_nb_of_pictures.append(item_nb_of_picture)

        # 2x2 item
        item_nb_of_picture = {
                    'name': '2x2',
                    'value': 2}
        list_nb_of_pictures.append(item_nb_of_picture)

        # 3x3 item
        item_nb_of_picture = {
                    'name': '3x3',
                    'value': 3}
        list_nb_of_pictures.append(item_nb_of_picture)

        # 4x4 item
        item_nb_of_picture = {
                    'name': '4x4',
                    'value': 4}
        list_nb_of_pictures.append(item_nb_of_picture)

        # 6x6 item
        item_nb_of_picture = {
                    'name': '6x6',
                    'value': 6}
        list_nb_of_pictures.append(item_nb_of_picture)

        # return the sizes at the end
        return list_nb_of_pictures

    def rss(self, author_key=None, collection_key=None,
            exposition_key=None):
        """
        """

        # set picture list for display
        picture_query = Picture().all()
        # select lanugage
        picture_query.filter('language =', self.language)

        # manage the author filter
        if author_key:
            author = Author.get(author_key)
            picture_query.filter('author =', author)
        else:
            author = None

        # manage the collection filter
        if collection_key:
            collection = Collection.get(collection_key)
            collection_query.filter('collection =', collection)
        else:
            collection = None

        # manage the exposition filter
        if exposition_key:
            exposition = Exposition.get(exposition_key)
            picture_query.filter('exposition =', exposition)
        else:
            exposition = None

        # set the order
        picture_query.order('title')

        # set the template for edit
        self.template_values['pictures'] = picture_query
        self.template_values['author'] = author
        self.template_values['collection'] = collection
        self.template_values['exposition'] = exposition

        # find the template
        path = os.path.join(os.path.dirname(__file__),
                                '../templates', 'picture', 'index.rss')

        # display the picture
        return template.render(path, self.template_values)

    def show(self, nb_of_pictures=2,
            offset=0, link_range=10, order='title',
            author_key=None, collection_key=None,
            exposition_key=None):
        """
        """
        # reset default nb_of_pictures value in case
        if nb_of_pictures == None or nb_of_pictures == '':
            nb_of_pictures = 2
        else:
            nb_of_pictures = int(nb_of_pictures)

        # reset default offset value in case
        if offset == None or offset == '':
            offset = 0
        else:
            offset = int(offset)

        # reset default link_range value in case
        if link_range == None or  link_range == '':
            link_range = 10
        else:
            link_range = int(link_range)

        # reset default link_range value in case
        if order == None or order == '':
            order = 'title'

        # set picture list for display
        picture_query = Picture().all()
        # select lanugage
        picture_query.filter('language =', self.language)

        # manage the author filter
        if author_key:
            author = Author.get(author_key)
            picture_query.filter('author =', author)
        else:
            author = None

        # manage the author filter
        if collection_key:
            collection = Collection.get(collection_key)
            picture_query.filter('collection =', collection)
        else:
            collection = None

        # manage the exposition filter
        if exposition_key:
            exposition = Exposition.get(exposition_key)
            picture_query.filter('exposition =', exposition)
        else:
            exposition = None

        # set the order
        picture_query.order(order)
        # fetch for safety reason
        nb_of_pictures_per_page = nb_of_pictures * nb_of_pictures
        fetched_pictures = picture_query.fetch(
                nb_of_pictures_per_page,
                offset=(offset * nb_of_pictures_per_page))

        # get the links depending of the number of pictures
        links = self.get_links(picture_query.count(),
                nb_of_pictures, offset, link_range)

        # get the formatted list of picture to display
        pictures = self.__get_pictures(
                fetched_pictures, nb_of_pictures)

        # get the author list
        author_query = Author().all()
        author_query.filter('language =', self.language)
        author_query.order('last_name')

        # get the collection list
        collection_query = Collection().all()
        collection_query.filter('language =', self.language)
        collection_query.order('title')

        # get the exposition list
        exposition_query = Exposition().all()
        exposition_query.filter('language =', self.language)
        exposition_query.order('title')

        # get the all_nb_of_pictures list
        all_nb_of_pictures = self.__get_all_nb_of_pictures()

        # set the template for edit
        self.template_values['action'] = 'picture'
        self.template_values['links'] = links
        self.template_values['pictures'] = pictures
        self.template_values['author'] = author
        self.template_values['collection'] = collection
        self.template_values['exposition'] = exposition
        self.template_values['authors'] = author_query
        self.template_values['collections'] = collection_query
        self.template_values['exposition'] = exposition
        self.template_values['expositions'] = exposition_query
        self.template_values['nb_of_pictures'] = nb_of_pictures
        self.template_values['all_nb_of_pictures'] = all_nb_of_pictures

        # find the template
        path = os.path.join(os.path.dirname(__file__),
                                '../templates', 'picture', 'index.html')

        # display the picture
        return template.render(path, self.template_values)

    def edit(self, picture_key, nb_of_pictures=2):
        """
        """
        # reset default nb_of_pictures value in case
        if nb_of_pictures == None or nb_of_pictures == '':
            nb_of_pictures = 2
        else:
            nb_of_pictures = int(nb_of_pictures)

        # get the picture
        picture = Picture().get(picture_key)

        # get language key for following updates
        language_key = self.language.key()

        # init with the default author if not already set
        if not picture.author:
            a_manager = author_manager.AuthorManager(
                    language_key=language_key)
            picture.author = a_manager.get_default_author()

        # init with the default collection if not already set
        if not picture.collection:
            c_manager = collection_manager.CollectionManager(
                    language_key=language_key)
            picture.collection = c_manager.get_default_collection()

        # init with the default exposition if not already set
        if not picture.exposition:
            e_manager = exposition_manager.ExpositionManager(
                    language_key=language_key)
            picture.exposition = e_manager.get_default_exposition()

        # in case of update
        picture.put()

        # get the author list
        author_query = Author().all()
        author_query.filter('language =', self.language)
        author_query.order('last_name')

        # get the collection list
        collection_query = Collection().all()
        collection_query.filter('language =', self.language)
        collection_query.order('title')

        # get the exposition list
        exposition_query = Exposition().all()
        exposition_query.filter('language =', self.language)
        exposition_query.order('title')

        # set the template for edit
        self.template_values['authors'] = author_query
        self.template_values['collections'] = collection_query
        self.template_values['expositions'] = exposition_query
        self.template_values['picture'] = picture
        self.template_values['nb_of_pictures'] = nb_of_pictures

        # find the template
        path = os.path.join(os.path.dirname(__file__),
                            '../templates', 'picture', 'edit.html')

        # display the picture
        return template.render(path, self.template_values)

    def new(self):
        """
        """
        # create the new picture
        picture = Picture()

        # requirement
        picture.title = db.Category(' ')

        # set the current language
        picture.language = self.language

        # get language key for following inits
        language_key = self.language.key()

        # init with the default author
        a_manager = author_manager.AuthorManager(
                language_key=language_key)
        picture.author = a_manager.get_default_author()

        # init with the default collection
        c_manager = collection_manager.CollectionManager(
                language_key=language_key)
        picture.collection = c_manager.get_default_collection()

        # init with the default exposition
        e_manager = exposition_manager.ExpositionManager(
                language_key=language_key)
        picture.exposition = e_manager.get_default_exposition()

        # save
        picture.put()

        return picture.key()

    def delete(self, picture_key):
        """
        """
        #
        picture = Picture().get(picture_key)

        # delete the picture
        picture.delete()

    def author(self, picture_key, author_key):
        """
        """
        # get the picture
        picture = Picture().get(picture_key)

        # get the author
        author = Author().get(author_key)

        # set the author
        picture.author = author

        # save
        picture.put()

    def collection(self, picture_key, collection_key):
        """
        """
        # get the picture
        picture = Picture().get(picture_key)

        # get the collection
        collection = Collection().get(collection_key)

        # set the collection
        picture.collection = collection

        # save
        picture.put()

    def exposition(self, picture_key, exposition_key):
        """
        """
        # get the picture
        picture = Picture().get(picture_key)

        # get the exposition
        exposition = Exposition().get(exposition_key)

        # set the exposition
        picture.exposition = exposition

        # save
        picture.put()

    def save(self, picture_key, title, info):
        """
        """
        #
        picture = Picture().get(picture_key)

        # title can t be empty
        title = title.strip()
        if title == '':
            title = ' '

        # set title
        picture.title = db.Category(title)

        # set info
        picture.info = info
        picture.html_info = self.get_html_content(info)

        # save picture
        picture.put()

    def save_picture_image(self, picture_key, url):
        """
        """
        # get the picture
        picture = Picture().get(picture_key)

        # set the image
        picture.url = url

        # save
        picture.put()

    def get_links(self, nb_of_all_img,
            nb_of_pictures, offset, link_range):
        """
        """
        # get the number of pages to manage
        number_of_pages = nb_of_all_img - 1
        number_of_pages /= nb_of_pictures * nb_of_pictures

        # list of links to return
        links = list()

        # set start link
        start_link = offset - (link_range / 2)
        if start_link < 0:
            start_link = 0

        # set end link
        end_link = offset + (link_range / 2)
        if end_link < link_range:
            end_link = link_range


        # do we need links?
        if number_of_pages > 0:
            # first item
            item_link = {
                        'id': '<<',
                        'offset': 0,
                        'input': True}
            links.append(item_link)

            # need previous link?
            if offset > 0 :
                item_link = {
                            'id': '<',
                            'offset': offset - 1,
                            'input': True}
                links.append(item_link)

            # always use an index its useful
            idx = start_link

            # the loop :)
            while idx < end_link \
            and idx <= number_of_pages:

                # add a new link
                item_link = {
                            'id': '%s' % (idx + 1),
                            'offset': idx,
                            'input': not idx==offset}
                links.append(item_link)

                # inc the idx
                idx += 1

            # need a next link
            if offset < number_of_pages:
                item_link = {
                            'id': '>',
                            'offset': offset + 1,
                            'input': True}
                links.append(item_link)

            # the last link
            item_link = {
                        'id': '>>',
                        'offset': number_of_pages,
                        'input': True}
            links.append(item_link)

        # return the list of links
        return links

    def __albums_and_images(self, album):
        """
        """
        list_albums = list()
        list_imgs = list()

        root_path = os.path.abspath('.')
        path = os.path.join(root_path, 'resources', 'img', 'gallery')
        for root, dirs, files in os.walk(path):
            for f in files:
                file_name = f.split('.')
                if len(file_name) > 1 \
                and (file_name[1] == 'jpg' or file_name[1] == 'JPG'):
                    img_dir = root.split('/')[-1]
                    if not img_dir in list_albums:
                        list_albums.append(img_dir)

                    if not album:
                        album = list_albums[0]

                    if img_dir == album:
                        url = os.path.join('gallery', img_dir, f)
                        url = url.replace('/', '-')
                        list_imgs.append(url)

        return list_albums, list_imgs

    def edit_image(self, picture_key, album=None,
            offset=0, link_range=10, page='picture'):
        """
        """
        # check the link_range
        if link_range == None or link_range == '':
            link_range = 10
        else:
            link_range = int(link_range)

        # reset default offset value in case
        if offset == None or offset == '':
            offset = 0
        else:
            offset = int(offset)

        albums, all_images = self.__albums_and_images(album)

        if album == None or album =='':
            album  = albums[0]

        nb_of_pictures_per_page = 25
        offset_1 = offset * nb_of_pictures_per_page
        offset_2 = (offset + 1) * nb_of_pictures_per_page
        images = all_images[offset_1:offset_2]

        # get the formatted list of picture to display
        table_of_images = self.__get_pictures(images, 5)

        # get the links depending of the number of pictures
        links = self.get_links(len(all_images),
                5, offset, link_range)

        # set the template for edit
        self.template_values['picture_key'] = picture_key
        self.template_values['page'] = page
        self.template_values['links'] = links
        self.template_values['albums'] = albums
        self.template_values['album'] = album
        self.template_values['images'] = table_of_images

        # find the template
        path = os.path.join(
                os.path.dirname(__file__),
                '../templates', 'picture', 'list_edit_image.html')

        # display the images
        return template.render(path, self.template_values)

    def save_image(self,
            url, width, height, content=False):
        """
        """
        img_query = Img().all()
        img_query.filter('url =', url)

        # img not found, create a new one
        if img_query.count() == 0:
            # add a new picture in the db
            img = Img()
            img.url = url
            img.content = content
            img.put()

        else:
            img = img_query.get()

        return img

    def delete_image(self, img_key):
        """
        """
        if not img_key or img_key == '':
            return

        img = Img().get(img_key)
        if img:
            img.delete()
